package com.nx.vip.anno;

import com.google.auto.service.AutoService;

import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.Name;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Set;

/**
 * 1、代码增强
 * 2、动态扩展
 * 实现方式
 * 1、注解处理器
 * 2、反射
 */
@AutoService(Processor.class) //使用google自动注册到mete-info下
@SupportedAnnotationTypes("com.nx.vip.anno.FiledAnno") //需要解析的注解
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class FiledAnnoProcessor extends AbstractProcessor {

    private StringBuilder sb = new StringBuilder();
    private  int count;

    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
    }

    /**
     * 只要实体类上增加了 @FiledAnno 就将实体类中属性保存到硬盘
     * @param annotations 需要哪些注解 只有 ： om.nx.vip.anno.FiledAnno一个注解
     * @param roundEnv  每次的环境
     * @return
     */
    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        //elementSet代表加了FiledAnno注解的所有元素（源码.java生成的语法树）
        Set<? extends Element> elementSet = roundEnv.getElementsAnnotatedWith(FiledAnno.class);

        for (Element element:elementSet){
            //由于该注解处理器是处理FiledAnno注解的，而FiledAnno注解只添加在filed
            VariableElement varField = (VariableElement) element;
            TypeElement enclosingElement = (TypeElement)varField.getEnclosingElement(); //父元素是一个类
            String className = enclosingElement.getQualifiedName().toString();
            Name fieldName = varField.getSimpleName();

            //拼接类和属性名
            sb.append("className = "+className).append("\n filedName = ").append(fieldName+"\n");

            //拼接属性上的注解
            FiledAnno anno = varField.getAnnotation(FiledAnno.class);
            sb.append("annoValue = " + anno.value());

            count++;
            sb.append("\n count = " +count +"\n");

        }

        genertateFile(sb.toString());
        return false;
    }

    private void genertateFile(String str) {
        FileWriter fileWriter = null;
        try {
            File file = new File("D:\\nxjy\\anno\\dbFile.txt");
            if (!file.exists()) file.createNewFile();
            fileWriter = new FileWriter(file);
            fileWriter.append(str);
            fileWriter.flush();
        }catch (Exception e){

        }finally {
            try {
                fileWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }
}
